﻿// <copyright file="Visual3DCollection.cs" company="Axelerate Solutions S.A.">
// Copyright (c) Axelerate Solutions S.A.  All rights reserved.
// </copyright>

namespace Axelerate.Silverlight3D.Media.Media3D
{
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;
    using System.Collections.Generic;
    using Axelerate.Silverlight3D.Controls;
    using System.Collections;
    using System.Collections.Specialized;

    
    
    /// <summary>
    /// File name: Visual3DCollection.cs
    /// Company: Axelerate Solutions S.A.
    /// Created By: Daniel Rojas
    /// Created Date: 10/16/2008 11:53:00 h.
    /// Description: Collection of Visual3D Elements
    ///   <Modifications>
    ///   </Modifications>
    /// </summary>
    public class Visual3DCollection : DependencyObjectCollection<Visual3D>
    {
        public Visual3DCollection()
            : base()
        {
            
        }
        internal void Render(Viewport3D Viewport, List<RenderEntity> entitiesToRender, List<ModelVisual3D> renderedVisuals)
        {
            
            foreach (Visual3D visual in this)
            {
                visual.Render(Viewport, entitiesToRender, renderedVisuals);
            }
        }

    }

    /// <summary>
    /// I do this class trying to emulate the PresentationFrameworkCollection that use the panel for store his childrens trying to fix the FindName method in the viewport.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class DependencyObjectCollection<T> : DependencyObject, IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable, INotifyCollectionChanged where T : DependencyObject
    {
        
        private ObservableCollection<T> innerList;

        public DependencyObjectCollection():base()
        {
            innerList = new ObservableCollection<T>();
            innerList.CollectionChanged += new NotifyCollectionChangedEventHandler(innerList_CollectionChanged);
        }

        private void innerList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            OnNotifyCollectionChanged(e);
        }

        #region IEnumerable<T> Members

        public IEnumerator<T> GetEnumerator()
        {
            return this.innerList.GetEnumerator();
        }

        #endregion

        #region ICollection<T> Members

        public void Add(T item)
        {
            this.innerList.Add(item);
        }

        public bool Contains(T item)
        {
            return this.innerList.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            this.innerList.CopyTo(array, arrayIndex);
        }

        public bool Remove(T item)
        {
            return this.innerList.Remove(item);
        }

        #endregion

        #region IList<T> Members

        public int IndexOf(T item)
        {
            return this.innerList.IndexOf(item);
        }

        public void Insert(int index, T item)
        {
            this.innerList.Insert(index, item);
        }

        public T this[int index]
        {
            get
            {
                return this.innerList[index];
            }
            set
            {
                this.innerList[index] = value;
            }
        }

        #endregion

        #region INotifyCollectionChanged Members

        public event NotifyCollectionChangedEventHandler CollectionChanged;

        private void OnNotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (this.CollectionChanged != null)
            {
                this.CollectionChanged(this, e);
            }
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.innerList.GetEnumerator();
        }

        #endregion

        #region ICollection Members

        public void CopyTo(Array array, int index)
        {
            ((ICollection)this.innerList).CopyTo(array, index);
        }

        public int Count
        {
            get { return this.innerList.Count; }
        }

        public bool IsSynchronized
        {
            get { return ((ICollection)this.innerList).IsSynchronized; }
        }

        public object SyncRoot
        {
            get { return ((ICollection)this.innerList).SyncRoot; }
        }

        #endregion

        #region IList<T> Members


        public void RemoveAt(int index)
        {
            this.innerList.RemoveAt(index);
        }

        #endregion

        #region ICollection<T> Members

        public void Clear()
        {
            this.innerList.Clear();
        }

        public bool IsReadOnly
        {
            get { return ((ICollection<T>)this.innerList).IsReadOnly;  }
        }

        #endregion

        #region IList Members

        public int Add(object value)
        {
            return ((IList)this.innerList).Add(value);
        }

        public bool Contains(object value)
        {
            return ((IList)this.innerList).Contains(value);
        }

        public int IndexOf(object value)
        {
            return ((IList)this.innerList).IndexOf(value);
        }

        public void Insert(int index, object value)
        {
            ((IList)this.innerList).Insert(index, value);
        }

        public bool IsFixedSize
        {
            get { return ((IList)this.innerList).IsFixedSize; }
        }

        public void Remove(object value)
        {
            ((IList)this.innerList).Remove(value);
        }

        object IList.this[int index]
        {
            get
            {
                return ((IList)this.innerList)[index];
            }
            set
            {
                ((IList)this.innerList)[index] = value;
            }
        }

        #endregion
    }
}
